/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-06-27     chenlei       the first version
 */
#include "uart_app.h"
#include "head.h"

#define DBG_TAG "uart_app"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

//串口设备变量
rt_device_t serial_2;                /* 串口2设备句柄 */
rt_device_t serial_3;                /* 串口3设备句柄 */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 配置参数 */

//信号量变量
rt_sem_t uart2_sem;
rt_sem_t uart3_sem;
//线程变量
rt_thread_t uart2_thread;
rt_thread_t uart3_thread;

uint8_t g_license_plate[K230BUFFER_SIZE] = {0};      //k230识别车牌号数据
uint8_t g_license_eg800k[9] = {1,1,1,1,1,1,1,1,1};     //eg800k接收车牌号数据
uint8_t right_car_flag_t = 0;
rt_mutex_t license_mutex;                            // 车牌号互斥锁

uint8_t get_right_car_flag(void);
void set_right_car_flag(void);

/*------------------------------USART2部分----------------------------- */
//串口2回调函数
static rt_err_t uart2_rx_callback(rt_device_t dev,rt_size_t size)
{
    //接收到数据释放信号量
    rt_sem_release(uart2_sem);
    return RT_EOK;
}
//串口2数据处理线程
//串口2用来处理k230发送的车牌号数据
//帧头 0xAA 帧尾 0xFF 完整的一帧数据  AA E9 B2 81 4C 46 4D 32 30 30 FF
void uart2_th_entry(void *parameter)
{
    uint8_t rx_data;              // 当前接收字节
    uint8_t buffer[K230BUFFER_SIZE]; // 数据缓冲区
    uint16_t data_cnt = 0;  // 数据计数器
    enum PROC_DATA_STATE state = STATE_WAIT_HEAD;

    while(1)
    {
        if(rt_device_read(serial_2, 0, &rx_data, 1) == 1)    //阻塞读取数据
        {
            switch(state)
            {
            case STATE_WAIT_HEAD:
                if(rx_data == K230DATA_HEAD)
                {
                    buffer[0] = rx_data;  // 存储帧头
                    data_cnt = 1;          // 重置计数器
                    state = STATE_RECV_DATA;
                }
                break;

            case STATE_RECV_DATA:
                buffer[data_cnt++] = rx_data;
                // 收到完整数据部分 + 帧尾位置
                if(data_cnt >= (K230DATA_LEN + 1))
                {
                    state = STATE_CHECK_TAIL;
                }
                break;

            case STATE_CHECK_TAIL:
                if(rx_data == K230DATA_TAIL)
                {
                    buffer[data_cnt] = rx_data;  // 存储帧尾
                    /* ---------- 完整帧处理 ---------- */
                    rt_memcpy(g_license_plate, buffer, K230BUFFER_SIZE);
                    rt_device_write(serial_2, 0, g_license_plate, K230BUFFER_SIZE);
                }
                // 无论帧尾是否匹配都重置状态机
                state = STATE_WAIT_HEAD;
                break;
            }
        }
        else
        {
            rt_sem_take(uart2_sem, RT_WAITING_FOREVER);
        }
    }
}

int uart2_init(void)
{
    rt_size_t ret = 0;
    /* 找串口设备 */
    serial_2 = rt_device_find(USART2_NAME);
    if(serial_2 == RT_NULL)
    {
        LOG_E("not find uart2\n");
        return RT_ERROR;
    }
    /* 配置串口参数 */
    ret = rt_device_control(serial_2, RT_DEVICE_CTRL_CONFIG, &config);
    if(ret != RT_EOK)
        {
            LOG_E("usart2 config faild\n");
            return RT_ERROR;
        }
    /* 打开串口设备 */
    ret = rt_device_open(serial_2,RT_DEVICE_FLAG_INT_RX);
    if(ret != RT_EOK)
    {
        LOG_E("usart2 open faild\n");
        return RT_ERROR;
    }
    /* 设置回调函数 */
    rt_device_set_rx_indicate(serial_2, uart2_rx_callback);
    /* 创建信号量  初始值为0*/
    uart2_sem = rt_sem_create("uart2", 0, RT_IPC_FLAG_PRIO);
    if(uart2_sem != RT_NULL)
        LOG_D("uart2_sem create sucess ...\n");
    /* 创建互斥锁*/
    license_mutex = rt_mutex_create("license", RT_IPC_FLAG_PRIO);
    if(license_mutex == RT_NULL)
    {
        LOG_E("create license_mutex faild ...\n");
        return RT_ERROR;
    }
    /* 创建串口2数据处理线程*/
    uart2_thread = rt_thread_create("uart2_th", uart2_th_entry, NULL, 256, 10, 10);
    if(uart2_thread != RT_NULL)
    {
        LOG_D("uart2_thread create sucess ...\n");
        rt_thread_startup(uart2_thread);
    }

    /* 发送字符串 */
    rt_device_write(serial_2, 0, "Hello", 5);

    return RT_EOK;
}
/*------------------------------------------------------------------------ */


/*------------------------------USART3部分-------------------------------- */
//串口3回调函数
rt_err_t uart3_rx_callback(rt_device_t dev,rt_size_t size)
{
    rt_sem_release(uart3_sem);

    return RT_EOK;
}
//串口3数据处理线程
//串口3用来处理EG800k发送的车牌号数据
//帧头 0xAA 帧尾 0xFF
void uart3_th_entry(void *parameter)
{
    uint8_t rx_data;              // 当前接收字节
    uint8_t buffer[MAX_FRAME_LEN];// 数据缓冲区
    uint16_t data_cnt = 0;        // 数据计数器
    enum PROC_DATA_STATE state = STATE_WAIT_HEAD;

    while(1)
    {
        // 阻塞读取单字节
        if(rt_device_read(serial_3, 0, &rx_data, 1) == 1)
        {
            switch(state)
            {
            case STATE_WAIT_HEAD:
                if(rx_data == EG800K_HEAD)
                {
                    buffer[0] = rx_data;  // 存储帧头
                    data_cnt = 1;         // 重置计数器
                    state = STATE_RECV_DATA;
                }
                break;

            case STATE_RECV_DATA:
                // 检查是否超过最大帧长度
                if(data_cnt >= MAX_FRAME_LEN)
                {
                    state = STATE_WAIT_HEAD; // 长度异常，重置状态机
                    LOG_W("Frame too long, reset state machine");
                    break;
                }

                buffer[data_cnt++] = rx_data;

                // 检查是否遇到帧尾
                if(rx_data == EG800K_TAIL)
                {
                    // 确认帧尾并处理帧
                    uint16_t payload_len = data_cnt - 2;
                    uint8_t *payload = &buffer[1];
                    if(payload_len == 4)       //AA 6C 6F 63 6B FF
                    {
                        char cmd[payload_len];
                        rt_memcpy(cmd, payload, payload_len);
                        if (rt_memcmp(cmd, CMD_LOCK, 4) == 0)
                        {
                            set_car_lock_state(STATE_SHOULD_RAISE);
                            rt_device_write(serial_3, 0, cmd, payload_len);
                        }
                    }
                    else if(payload_len == 6)   //AA 75 6E 6C 6F 63 6B FF
                    {
                        char cmd[payload_len];
                        rt_memcpy(cmd, payload, payload_len);
                        if (rt_memcmp(cmd, CMD_UNLOCK, 6) == 0)
                        {
                            set_car_lock_state(STATE_SHOULD_FALL);
                            rt_device_write(serial_3, 0, cmd, payload_len);
                        }
                    }
                    else if(payload_len == 9)   //AA E9 B2 81 4C 46 4D 32 30 30 FF
                    {
//                        char proc_data[payload_len];
//                        rt_memcpy(proc_data, payload, payload_len);
                        rt_memcpy(g_license_eg800k, payload, payload_len);
//                        if(rt_memcmp(g_license_eg800k, g_license_plate + 1, 9) == 0)
//                        {
//                            set_right_car_flag();
//                            rt_memset(g_license_eg800k, 0, sizeof(g_license_eg800k));
//                            rt_memset(g_license_plate, 0, sizeof(g_license_plate));
//                            rt_device_write(serial_3, 0, "YES", 3);
//                        }

                    }
                    // 无论帧尾是否匹配都重置状态机
                    state = STATE_WAIT_HEAD;
                    data_cnt = 0;
                }
                break;


            }
        }
        else // 无数据时挂起线程
        {
            rt_sem_take(uart3_sem, RT_WAITING_FOREVER);
        }
    }
}


int uart3_init(void)
{
    rt_size_t ret = 0;
    /* 找串口设备 */
    serial_3 = rt_device_find(USART3_NAME);
    if(serial_3 == RT_NULL)
    {
        LOG_E("not find uart3\n");
        return RT_ERROR;
    }
    /* 配置串口参数 */
    ret = rt_device_control(serial_3, RT_DEVICE_CTRL_CONFIG, &config);
    if(ret != RT_EOK)
        {
            LOG_E("usart3 config faild\n");
            return RT_ERROR;
        }
    /* 打开串口设备 */
    ret = rt_device_open(serial_3,RT_DEVICE_FLAG_INT_RX);
    if(ret != RT_EOK)
    {
        LOG_E("usart3 open faild\n");
        return RT_ERROR;
    }
    /* 设置回调函数 */
    rt_device_set_rx_indicate(serial_3, uart3_rx_callback);
    /* 创建信号量  初始值为0*/
    uart3_sem = rt_sem_create("uart3", 0, RT_IPC_FLAG_PRIO);
    if(uart3_sem != RT_NULL)
        LOG_D("uart3_sem create sucess ...\n");
    /* 创建串口2数据处理线程*/
    uart3_thread = rt_thread_create("uart3_th", uart3_th_entry, NULL, 512, 10, 10);
    if(uart3_thread != RT_NULL)
    {
        LOG_D("uart3_thread create sucess ...\n");
        rt_thread_startup(uart3_thread);
    }

    /* 发送字符串 */
    rt_device_write(serial_3, 0, "Hello", 5);

    return RT_EOK;
}


uint8_t get_right_car_flag(void)
{
    uint8_t temp;
    rt_mutex_take(license_mutex, RT_WAITING_FOREVER);
    temp = right_car_flag_t;
    right_car_flag_t = 0;
    rt_mutex_release(license_mutex);
    return temp;
}

void set_right_car_flag(void)
{
    if(rt_memcmp(g_license_eg800k, g_license_plate + 1, 9) == 0)
    {
        rt_memset(g_license_eg800k, 1, sizeof(g_license_eg800k));
        rt_memset(g_license_plate, 0, sizeof(g_license_plate));
        rt_mutex_take(license_mutex, RT_WAITING_FOREVER);
        right_car_flag_t = 1;
        rt_mutex_release(license_mutex);
        rt_device_write(serial_3, 0, "YES", 3);
    }

}


